package com.sz.mes.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.V;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Pagination;
import com.sz.mes.dto.ProductTaskDTO;
import com.sz.mes.dto.TechDTO;
import com.sz.mes.entity.*;
import com.sz.mes.mapper.*;
import com.sz.mes.service.ProductTaskService;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产任务相关Service实现
 *
 * @author hem
 * @version 1.0
 * @date 2023-05-19
 * Copyright © szhs
 */
@Service
@Slf4j
public class ProductTaskServiceImpl extends BaseCustomServiceImpl<ProductTaskMapper, ProductTask> implements ProductTaskService {
    private final ProductTaskMapper productTaskMapper;
    private final TableHeadMapper tableHeadMapper;
    private final MaterialMapper materialMapper;
    private final TechniqueMapper techniqueMapper;
    private final TechMapper techMapper;

    public ProductTaskServiceImpl(ProductTaskMapper productTaskMapper, TableHeadMapper tableHeadMapper, MaterialMapper materialMapper, TechniqueMapper techniqueMapper, TechMapper techMapper) {
        this.productTaskMapper = productTaskMapper;
        this.tableHeadMapper = tableHeadMapper;
        this.materialMapper = materialMapper;
        this.techniqueMapper = techniqueMapper;
        this.techMapper = techMapper;
    }

    public JsonResult insert(ProductTask entity) {
        ProductTask productTask = new ProductTask();
        productTask.setExcelData(entity.getExcelData());
        try {
//            productTaskMapper.insert(productTask);
            if (productTask.getExcelData() != null) {
                return dataProcess(productTask.getExcelData(), productTask.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return JsonResult.OK("导入数据成功");
    }


    //Excel 数据解析导入基础表
    JsonResult dataProcess(String excelData, Long productTaskId) throws ParseException {
        //mapList 获取到所有的数据
        ArrayList<Map<String, String>> mapList = new ArrayList<>();


        //hashMap 表头对应的 序号
        HashMap<String, String> hashMap = new HashMap<>();
        //获取表头
        TableHead tableHead = tableHeadMapper.selectById(3);

        String data = tableHead.getData();
//        String replaceAll = data.replaceAll("\\\\", "");
//        System.out.println(data);
//        System.out.println(replaceAll);

        JSONObject jsonObject = JSONObject.parseObject(tableHead.getData());
        for (Object map : jsonObject.entrySet()) {
//            hashMap.put(String.valueOf(((Map.Entry)map).getValue()),String.valueOf(((Map.Entry)map).getKey()));
            hashMap.put(String.valueOf(((Map.Entry) map).getKey()), String.valueOf(((Map.Entry) map).getValue()));
        }

        //获取完表头信息后清楚数据，给其他数据用
        mapList.clear();

        System.out.println("excelData:" + excelData);

        //json转为List
        JSONArray objects = JSONObject.parseArray(excelData);
//        JSONArray objects = JSONObject.parseArray(JSONObject.toJSONString(excelData));
        for (Object object : objects) {
            HashMap<String, String> map1 = JSONObject.parseObject(JSONObject.toJSONString(object), HashMap.class);
            mapList.add(map1);
        }

        System.out.println("mapList:" + mapList);

        for (Map map : mapList) {
            System.out.println(map);
            //任务单
            ProductTask productTask = new ProductTask();
            String receiptNum = (String) map.get(hashMap.get("单据编号"));
            String substringNum = receiptNum.substring(2);
            productTask.setTaskNum("RWD" + substringNum);
//            productTask.setReceiptNum((String) map.get(hashMap.get("单据编号")));
            productTask.setReceiptNum(receiptNum);
            productTask.setPlanNum((String) map.get(hashMap.get("计划号")));
            productTask.setProductNum(((String) map.get(hashMap.get("料品料号"))));
            productTask.setProductName((String) map.get(hashMap.get("料品名称")));
            productTask.setProductSpecification((String) map.get(hashMap.get("料品规格")));
            productTask.setProductUnit((String) map.get(hashMap.get("生产单位")));
            productTask.setProductSection((String) map.get(hashMap.get("生产部门")));
            productTask.setInstockQuantity((String) map.get(hashMap.get("入库数量")));
            productTask.setStockNum(((String) map.get(hashMap.get("备料料号"))));
            productTask.setStockName((String) map.get(hashMap.get("备料名称")));
            productTask.setStockSpecification((String) map.get(hashMap.get("备料规格")));
            productTask.setUnit((String) map.get(hashMap.get("订单备料.料品.库存单位")));
            productTask.setStockDosage((String) map.get(hashMap.get("备料用量")));
            productTask.setStockProvideTime((String) map.get(hashMap.get("备料发料日期")));
            productTask.setStockProvideQuantity((String) map.get(hashMap.get("备料已发放数量")));


//            Long taskQuantity = (Long) map.get(hashMap.get("生产数量"));
            Integer taskQuantity = (Integer) map.get(hashMap.get("生产数量"));
            if (taskQuantity != 0) {
                productTask.setQuantity(taskQuantity);
            } else {
//                productTask.setQuantity(0L);
                productTask.setQuantity(0);
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            if (!" ".equals(map.get(hashMap.get("计划开工日期"))) && !" ".equals(map.get(hashMap.get("计划完工日期")))) {
                String startWorkTime = (String) (map.get(hashMap.get("计划开工日期")));
                String finishWorkTime = (String) (map.get(hashMap.get("计划完工日期")));
////                String formattedDate = sdf.format(date);
//                SimpleDateFormat startTime = (SimpleDateFormat) map.get(hashMap.get("开始时间"));
//                SimpleDateFormat finishTime = (SimpleDateFormat) map.get(hashMap.get("结束时间"));
                Date startTime = sdf.parse(startWorkTime);
                Date finishTime = sdf.parse(finishWorkTime);
                long start = startTime.getTime();
                long finish = finishTime.getTime();
                if (finish < start) {
                    return JsonResult.FAIL_OPERATION("完工日期不能早于开工日期");
                } else {
                    productTask.setStartTime(startTime);
                    productTask.setEndTime(finishTime);
//                    productTask.setStartTime(startWorkTime);
//                    productTask.setEndTime(finishWorkTime);
                }
            }


            try {
                productTask.setExcelData(excelData);
                productTaskMapper.insert(productTask);
            } catch (Exception e) {
                return JsonResult.FAIL_OPERATION("插入失败" + e.getMessage());
            }
            //任务单处理结束
        }

        return JsonResult.OK("数据导入成功");
    }

    @Override
    public Map<String, Object> getList(ProductTaskDTO queryDto) {
        HashMap<String, Object> map = new HashMap<>();
        QueryWrapper<ProductTask> pqw = new QueryWrapper<>();
        if (!StringUtils.isEmpty(queryDto.getTaskNum())) {
            pqw.eq("task_num", queryDto.getTaskNum());
        }
        if (!StringUtils.isEmpty(queryDto.getPlanNum())) {
            pqw.eq("plan_num", queryDto.getPlanNum());
        }
        pqw.eq("is_deleted", 0);
        Page<ProductTask> page = new Page<ProductTask>(queryDto.getPageNumber(), queryDto.getPageSize());
        Page<ProductTask> productTaskPage = productTaskMapper.selectPage(page, pqw);
        List<ProductTask> records = productTaskPage.getRecords();
        for (ProductTask productTaskInfo : records) {
            QueryWrapper<Technique> tqw = new QueryWrapper<>();
            tqw.eq("task_num", productTaskInfo.getTaskNum());
            List<Technique> techniques = techniqueMapper.selectList(tqw);
            productTaskInfo.setTechniqueList(techniques);
        }

        map.put("data", productTaskPage.getRecords());
        map.put("total", productTaskPage.getTotal());
        return map;
    }


    /**
     * 工艺详情的插入
     *
     * @param technique
     * @return
     */
    @Override
    public JsonResult insertTechnologyInfo(Technique technique) {
        String equipment = technique.getEquipment();
        String[] equipmentArray = equipment.split(",");
        for (String equip : equipmentArray) {
            technique.setEquipment(equip);
            productTaskMapper.insertTechnologyInfo(technique);
        }
        return JsonResult.OK(technique);
    }


    @Override
    public JsonResult getProductSchedule(ProductTaskDTO queryDto, Pagination pagination) {
        Page<ProductTask> page = new Page<>(pagination.getPageIndex(),pagination.getPageSize());
        QueryWrapper<ProductTask> pqw = new QueryWrapper<>();
        if (StringUtils.isNotBlank(queryDto.getProductSpecification())){
            pqw.like("product_specification",queryDto.getProductSpecification());

        }else if (StringUtils.isNotBlank(queryDto.getProductName())){
            pqw.like("product_name",queryDto.getProductName());

        }else if (StringUtils.isNotBlank(queryDto.getReceiptNum())){
            pqw.like("receipt_num",queryDto.getReceiptNum());

        }else if (StringUtils.isNotBlank(queryDto.getProductNum())){
            pqw.like("product_num",queryDto.getProductNum());

        }else if (StringUtils.isNotBlank(queryDto.getPlanNum())){
            pqw.like("plan_num",queryDto.getPlanNum());
        }
//        pqw.last("ORDER BY id DESC");
        Page<ProductTask> productTaskPage = productTaskMapper.selectPage(page, pqw);
        List<String> taskNumList = productTaskPage.getRecords().stream().map(ProductTask::getTaskNum).collect(Collectors.toList());
        QueryWrapper<Tech> techqw = new QueryWrapper<>();
        if(taskNumList.size() != 0 && taskNumList != null){

            techqw.in("task_num",taskNumList);

        }
        List<Tech> techList = techMapper.selectList(techqw);
//        List<Tech> list = techList.stream().filter(tech -> tech.getTaskNum().equals(productTask.getTaskNum())).collect(Collectors.toList());

        ArrayList<ProductTaskDTO> productTaskDTOS = new ArrayList<>();
        for (ProductTask productTask:productTaskPage.getRecords()){
            ProductTaskDTO productTaskDTO = new ProductTaskDTO();
            productTaskDTO.setId(productTask.getId());
            productTaskDTO.setTaskNum(productTask.getTaskNum());
            productTaskDTO.setReceiptNum(productTask.getReceiptNum());
            productTaskDTO.setPlanNum(productTask.getPlanNum());
            productTaskDTO.setProductNum(productTask.getProductNum());
            productTaskDTO.setProductName(productTask.getProductName());
            productTaskDTO.setProductSpecification(productTask.getProductSpecification());
            productTaskDTO.setQuantity(productTask.getQuantity());
            productTaskDTO.setProductUnit(productTask.getProductUnit());
            productTaskDTO.setProductSection(productTask.getProductSection());
            productTaskDTO.setStartTime(productTask.getStartTime());
            productTaskDTO.setEndTime(productTask.getEndTime());
            productTaskDTO.setInstockQuantity(productTask.getInstockQuantity());
            productTaskDTO.setStockNum(productTask.getStockNum());
            productTaskDTO.setStockName(productTask.getStockName());
            productTaskDTO.setStockSpecification(productTask.getStockSpecification());
            productTaskDTO.setUnit(productTask.getUnit());
            productTaskDTO.setStockDosage(productTask.getStockDosage());
            productTaskDTO.setStockProvideTime(productTask.getStockProvideTime());
            productTaskDTO.setStockProvideQuantity(productTask.getStockProvideQuantity());
            productTaskDTO.setProductTaskCreateTime(productTask.getProductTaskCreateTime());

            List<Tech> list = techList.stream().filter(tech -> tech.getTaskNum().equals(productTask.getTaskNum())).collect(Collectors.toList());
            ArrayList<TechDTO> techDTOS = new ArrayList<>();
            for (Tech tech : list){
                TechDTO techDTO = new TechDTO();
                techDTO.setTechName(tech.getTechName());
                techDTO.setEquipment(tech.getEquipment());
                techDTO.setTaskNum(tech.getTaskNum());

                QueryWrapper<Technique> techniqueQueryWrapper = new QueryWrapper<>();
                techniqueQueryWrapper.eq("task_num",tech.getTaskNum());
                techniqueQueryWrapper.eq("tech_name",tech.getTechName());
                List<Technique> techniqueList = techniqueMapper.selectList(techniqueQueryWrapper);
                if (techniqueList != null && techniqueList.size() != 0){
                    Long goodQuantity = techniqueList.stream().mapToLong(Technique::getGoodQuantity).sum();
                    techDTO.setGoodQuantity(goodQuantity);
                }else {
                    techDTO.setGoodQuantity(0L);
                }

                techDTOS.add(techDTO);
            }
            productTaskDTO.setTechList(techDTOS);
            productTaskDTOS.add(productTaskDTO);

        }
        pagination.setTotalCount(page.getTotal());
        return JsonResult.OK(productTaskDTOS).bindPagination(pagination);
    }



    @Override
    public JsonResult getGoods(String receiptNum) {
        QueryWrapper<ProductTask> productTaskQueryWrapper = new QueryWrapper<>();
        productTaskQueryWrapper.eq("receipt_num", receiptNum);
        List<ProductTask> productTasks = productTaskMapper.selectList(productTaskQueryWrapper);
        return JsonResult.OK(productTasks);
    }

    @Override
    public List<String> filterDuplicate(List<String> receiptNumAndStockNumList) {
        if (V.isEmpty(receiptNumAndStockNumList)) {
            return Collections.emptyList();
        }

        List<String> duplicateData = productTaskMapper.selectDuplicateData(receiptNumAndStockNumList);
//        LambdaQueryWrapper<ProductTask> wrapper = new LambdaQueryWrapper<>();
//        wrapper.in(ProductTask::getSplice, receiptNumAndStockNumList);
//        List<String> receiptNumAndStockNumLists = getValuesOfField(productTaskQueryWrapper, ProductTask::getSplice);


        return duplicateData;
    }
}
